import os
from flask import Blueprint, jsonify, redirect, url_for, session, Response, make_response
from camera import VideoCamera
from easyRead.models import User
import cv2
import face_recognition


bp = Blueprint("faceDetection", __name__, url_prefix="/users")
current_dir = os.getcwd()
face_cascade = cv2.CascadeClassifier("../face_model/haarcascade_frontalface_default.xml")

# 获取视频流
def video_stream():
    global video_camera
    global global_frame

    if video_camera is None:
        video_camera = VideoCamera()

    while True:
        frame = video_camera.get_frame()
        if frame is not None:
            global_frame = frame
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
        else:
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + global_frame + b'\r\n\r\n')


# 视频流
@bp.route('/video_viewer')
def video_viewer():
    # 模板渲染
    user = session.get("user")
    if not user:
        return redirect(url_for("user.login"))
    return Response(video_stream(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


# 人脸识别登录模块
@bp.route("/faceLogin", methods=['GET'])
def faceLogin():
    users = User.query.filter(User.faceDetection == 1).all()
    # 构建图像文件路径
    image_file = os.path.join(current_dir, "img", "%s.jpg")
    # 加载当前帧的图像并检测其中的人脸
    video_capture = cv2.VideoCapture(0)
    ret, frame = video_capture.read()
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    face_locations = face_recognition.face_locations(small_frame)
    # 将当前帧图像中人脸与系统中人脸进行比较
    for i in range(len(users)):
        # 加载一张包含已知人脸的图片并将其编码
        known_image = face_recognition.load_image_file(image_file % users[i].id)
        known_face_encoding = face_recognition.face_encodings(known_image)[0]
        # 将检测到的每个人脸编码并与已知人脸的编码进行比较
        face_encodings = face_recognition.face_encodings(small_frame, face_locations)
        for face_encoding in face_encodings:
            # 查看脸部是否与已知脸部相匹配（S）
            match = face_recognition.compare_faces([known_face_encoding], face_encoding)
            if match[0]:
                user = users[i]
                session['user'] = user
                return make_response(jsonify("用户人脸登录成功！"))
    return make_response(jsonify("人脸认证失败！"))


# 已登录用户添加人脸识别
@bp.route("/addFaceLogin", methods=['GET'])
def addFaceLogin():
    video_capture = cv2.VideoCapture(0)
    ret, frame = video_capture.read()
    message = "图片保存成功！"
    if ret:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
        if len(faces) == 0:
            message = "图片中不包含人脸，请重试！"
        elif len(faces) > 1:
            message = "录入图片只能包含一张人脸，请重试！"
        else:
            output_path = os.path.join(current_dir, "img")
            cv2.imwrite(output_path, frame)
    else:
        message = "图片保存失败！"
    return make_response(jsonify(message))